<?php
/**
 * FieldRenderer renders the fields of the EDO objects
 * 
 * This package replaces the deprecated DatatypeRenderer from the Global scope
 * 
 * @package EDO
 * @subpackage UI
 * @license BSD
 * @author Mikko Forsström
 * @author Mikko Hämäläinen
 *
 */
class FieldRenderer
{

    private $_ownerStack = array();
    
	protected $edo;
	
	protected $_renderers;

	/**
	 * This searcher is used for searching renderer classes
	 * @var FileSearher $classSearcher
	 */
	public $classSearcher;
	
	/**
	 * This is used by the individual renderers to find their templates
	 *
	 * @var FileSearcher $templateSearcher
	 */
	public $templateSearcher;
	
	static private $_instance;
	
	private function __construct()
	{
		// this searcher is used for searching renderer classes
		$this->classSearcher = new FileSearcher();
		$this->classSearcher->addSearchPath(dirname(__FILE__)."/renderers");
		$baserenderer = $this->classSearcher->find("renderer_base.php");
		
		$this->templateSearcher = new DirectorySearcher();
		$this->templateSearcher->addSearchPath(dirname(__FILE__)."/renderers/templates");
		
		require_once($baserenderer);#dirname(__FILE__)."/renderers/renderer_base.php");
	}

	
	static public function getInstance()
	{
        if (!self::$_instance instanceof self) {
           self::$_instance = new self();
        }

        return self::$_instance;
	}
	
	
	public function getOwnerStack()
	{
	    return $this->_ownerStack;
	}
	
	public function stackOwner($stackOwner)
	{
	    array_push($this->_ownerStack, $stackOwner);
	}
	
	public function unstackOwner()
	{
	    array_pop($this->_ownerStack);
	}
	
	
	
	public function render(EDO_object_basic $rObject, $fieldName, $renderMode = 'view', $config = array())
	{
		static $validationValues;
		if(!$validationValues)
		{
			$lead = LEAD::application();
			$validationValues = $lead->session->subSession('validationValues');
		}
				
				
		$fObject = $rObject->getFieldObject($fieldName);
		
		$validationValue = $validationValues->get($fieldName);
		if($validationValue !== false)
			$fObject->setValue($validationValue, false);
				
        	
		
		if(!isset($this->_renderers[$fObject->getType()]))
		{
            $rendererClass = false;
            $refleClass = new ReflectionClass($fObject);
            do
            {
                $classEnd = explode('_', $refleClass->getName(), 2);
                
                $classEnd = array_pop($classEnd);
                                
                $className = "renderer_{$classEnd}";
                 
                $foundRenderer = $this->classSearcher->find("{$className}.php");
                
                if(is_readable($foundRenderer))
                {
                	$rendererClass = $className;
                }
                if(!$rendererClass)
                    $refleClass = $refleClass->getParentClass();
                               
            } while($rendererClass === false);
		    
		    			
			#require_once dirname(__FILE__). "/renderers/{$rendererClass}.php";
			require_once($foundRenderer);
			$this->_renderers[$fObject->getType()] = new $rendererClass();
		}

		$renderer = $this->_renderers[$fObject->getType()];
        
		$renderFunc = $renderMode . 'Render';
		if(is_callable(array($renderer, $renderFunc)))
            return $renderer->$renderFunc($fObject);
        else 				
		  return $renderer->render($fObject, $renderMode, $config);
		
	}	
}
